package faktorI;

import java.util.Stack;

public class Calculator {
	private static Stack<PredElem> operatorStack;
	private static Stack<PredElem> operandStack;
	private static LstPredElem lista;
	private static PredElem element;
	private static String text;
	
	public static String calculate(Pravilo pravilo){
		PredElem.resetId();
		text ="Računamo meru poverenja i meru nepovernja" +
				"\npretpostavke:" +
				"\n" + pravilo.getPreduslov() +
				"\npravila P" + pravilo.getRedniBroj() + ":"
				;
		lista = pravilo.getPreduslov().getElemList();
		Iterator iterator = new Iterator(lista);
		iterator.first();
		operatorStack = new Stack<PredElem>();
		operandStack = new Stack<PredElem>();
		do{
			element = (PredElem)iterator.currentItem();
			iterator.next();
			if(element.jeOperand()){
				operandStack.push(element);
			}
			if(element.jeOperator()){
				evaluateOperator(element);
			}
			element = (PredElem)iterator.currentItem();
		}while(element != null);
		
		while(!operatorStack.empty()){
			PredElem operator = (PredElem)operatorStack.pop();
			PredElem left = (PredElem)operandStack.pop();
			PredElem right = (PredElem)operandStack.pop();
			PredElem result;
			result = evaluate (operator, left, right);
			operandStack.push(result);
		}
		PredElem result = operandStack.pop();
		
		text += "\nMB(eP"+ pravilo.getRedniBroj() +") ="
		+ "\nMB("+ result+") = " + result.getMB()
		+ "\nMD(eP"+ pravilo.getRedniBroj() +") =" +
		"\nMD("+ result +") = " + result.getMD()	
		;
		pravilo.getPreduslov().setMB(result.getMB());
		pravilo.getPreduslov().setMD(result.getMD());
		
		return text;
	}
	
	static void evaluateOperator(PredElem operator){
		boolean done = false;
		do{
			if(operatorStack.isEmpty() || "(".equals(operator.naziv)){
				operatorStack.push(operator);
				done = true;
			}
			else if(operator.getPrecedence()>operatorStack.peek().getPrecedence()){
				operatorStack.push(operator);
				done = true;
			}
			else{
				PredElem temp = operatorStack.pop();
				if("(".equals(temp.naziv)){
					done = true;
				}
				else{
					PredElem left = operandStack.pop();
					PredElem right = operandStack.pop();
					PredElem result;
					result = evaluate (temp, left, right);
					operandStack.push(result);
				}
			}
		}while(!done);	
	}
	
	static PredElem evaluate(PredElem operator, PredElem left,PredElem right){
		PredElem result = new PredElem();
		if("I".equals(operator.getNaziv())){
			result.setMB(min (left.getMB(), right.getMB()));
			result.setMD(max (left.getMD(), right.getMD()));
			text += "\nPošto je u pitanju konjukcija:" +
					"\nMB("+ left +" I "+ right +")=" +
					"\nmin (MB("+left+"), MB("+right+")";
			text += "\nRačunamo MB("+result+")= " +
					"\nmin ("+left.getMB()+","+right.getMB()+") = " + result.getMB();
			text += "\nRačunamo MD("+result+")= " +
					"\nmax ("+left.getMD()+","+right.getMD()+") = " + result.getMD()+ "\n";
			
		}
		else if ("ILI".equals(operator.getNaziv())){
			result.setMB(max (left.getMB(), right.getMB()));
			result.setMD(min (left.getMD(), right.getMD()));
			text += "\nPošto je u pitanju disjunkcija:" +
					"\nMB("+ left +" ILI "+ right +")=" +
					"\nmax (MB("+left+"), MB("+right+")";
			text += "\nRačunamo MB("+result+")= " +
					"\nmax (MB("+left.getMB()+"), MB("+right.getMB()+")) = " + result.getMB();
			text += "\nRačunamo MD("+result+")= " +
					"\nmin (MD("+left.getMD()+"), MD("+right.getMD()+")) = " + result.getMD() + "\n";
		}
		else throw new Greska("Pogrešan operator!Nije moguće izračunati faktor izvesnosti." + operator);
		return result;
	}
	
	public static double max(double a, double b){
		if(a>=b)return a;
		else return b;
	}
	public static double min(double a, double b){
		if(a<=b)return a;
		else return b;
	}
}
